"""
独立的钉钉智能体模块
专门处理钉钉办公功能：待办事项、日程安排、联系人查询等
"""

import os
import logging
from typing import Dict, Any, List
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage, AIMessage
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain_core.tools import Tool

logger = logging.getLogger(__name__)


class DingTalkAgent:
    """
    独立的钉钉智能体
    专门处理钉钉办公功能
    """
    
    def __init__(self, dingtalk_tools: List = None):
        """
        初始化钉钉智能体

        Args:
            dingtalk_tools: 钉钉工具列表（可选，如果不提供将自动初始化）
        """
        # 如果没有提供工具，则自动初始化
        if dingtalk_tools is None:
            self.dingtalk_tools = self._init_dingtalk_tools()
        else:
            self.dingtalk_tools = dingtalk_tools

        self.model = ChatOpenAI(
            model=os.getenv("BASE_MODEL", "gpt-4o-mini"),
            api_key=os.getenv("OPENAI_API_KEY"),
            base_url=os.getenv("OPENAI_BASE_URL"),
            temperature=0.1
        )

        # 创建钉钉专业prompt
        self.prompt = self._create_dingtalk_prompt()

        # 创建智能体
        self.agent = self._create_agent()

        logger.info(f"DingTalk Agent initialized with {len(self.dingtalk_tools)} tools")

    def _init_dingtalk_tools(self) -> List:
        """
        初始化钉钉工具（从 Agents.py 迁移的逻辑）

        Returns:
            钉钉工具列表
        """
        try:
            from .Tools import (
                create_todo, checkSchedule, SetSchedule,
                SearchSchedule, ModifySchedule, DelSchedule, ConfirmDelSchedule
            )

            # 创建钉钉工具列表
            dingtalk_tools = [
                create_todo, checkSchedule, SetSchedule,
                SearchSchedule, ModifySchedule, DelSchedule, ConfirmDelSchedule
            ]

            print(f"✅ 钉钉工具初始化成功，加载 {len(dingtalk_tools)} 个工具")
            logger.info(f"DingTalk tools initialized successfully: {len(dingtalk_tools)} tools")

            return dingtalk_tools

        except ImportError as e:
            logger.warning(f"钉钉工具模块不可用: {e}")
            print("❌ 钉钉工具不可用，将创建空的钉钉智能体以保持架构一致性")
            return []

        except Exception as e:
            logger.error(f"钉钉工具初始化失败: {e}")
            print("❌ 钉钉工具初始化失败，将创建空的钉钉智能体以保持架构一致性")
            return []

    def _create_dingtalk_prompt(self) -> ChatPromptTemplate:
        """创建钉钉智能体的专业prompt"""
        
        system_prompt = """你是一个专业的钉钉办公助手，专门帮助用户处理钉钉相关的办公功能。

🔧 **你的专业领域**：
• 待办事项管理：创建、查看、完成、删除待办任务
• 日程安排：查看日程、创建会议、搜索日程、修改日程
• 联系人查询：搜索同事信息、查找通讯录

🎯 **工作原则**：
1. 专注于钉钉办公功能，不处理其他领域的问题
2. 使用友好、专业的语调与用户交流
3. 主动询问必要的详细信息以完成任务
4. 提供清晰的操作反馈和结果说明
5. 遇到错误时提供有用的解决建议
6. 理解确认性回复，如"不用，你继续添加"表示确认执行之前讨论的操作
7. 根据上下文信息执行相应的钉钉操作

💡 **交互指南**：
• 当用户请求不明确时，主动询问具体需求
• 操作成功后，提供清晰的确认信息
• 操作失败时，解释原因并提供替代方案
• 始终保持耐心和专业态度

🚀 **可用功能**：
- 创建待办事项：帮助用户记录和管理任务
- 查看日程安排：显示用户的日程和会议
- 搜索联系人：查找同事的联系信息
- 会议管理：创建、修改、删除会议安排

🎯 **执行指南**：
- 当用户查询包含"请继续将...添加到我的日程中"时，提取时间和标题信息直接调用SetSchedule工具
- 当用户查询包含"请继续为我创建...待办事项"时，提取标题信息直接调用CreateTodo工具
- 当用户提供了完整信息时，立即执行操作而不是再次询问
- 优先使用工具完成任务，而不是只提供建议

请根据用户的具体需求，选择合适的工具来完成任务。如果用户的请求超出了钉钉办公功能范围，请礼貌地说明你的专业领域，并建议用户咨询其他助手。"""

        return ChatPromptTemplate.from_messages([
            ("system", system_prompt),
            ("human", "{input}"),
            ("placeholder", "{agent_scratchpad}")
        ])
    
    def _create_agent(self) -> AgentExecutor:
        """创建钉钉智能体执行器"""
        try:
            if not self.dingtalk_tools:
                logger.warning("No DingTalk tools available")
                return None
            
            # 创建工具代理
            agent = create_openai_tools_agent(
                llm=self.model,
                tools=self.dingtalk_tools,
                prompt=self.prompt
            )
            
            # 创建执行器
            agent_executor = AgentExecutor(
                agent=agent,
                tools=self.dingtalk_tools,
                verbose=True,
                handle_parsing_errors=True,
                max_iterations=3,
                early_stopping_method="generate"
            )
            
            return agent_executor
            
        except Exception as e:
            logger.error(f"Failed to create DingTalk agent: {e}")
            return None
    
    def process_request(self, user_input: str, user_id: str = None, rewrite_info: Dict = None) -> Dict[str, Any]:
        """
        处理用户的钉钉相关请求

        Args:
            user_input: 用户输入（可能是重写后的查询）
            user_id: 用户ID
            rewrite_info: 查询重写信息（包含原始查询和上下文）

        Returns:
            处理结果
        """
        try:
            if not self.agent:
                return {
                    "success": False,
                    "output": "抱歉，钉钉智能体暂时不可用。请稍后再试。",
                    "error": "Agent not initialized"
                }

            # 清理用户输入（移除对话历史）
            clean_input = self._clean_user_input(user_input)

            # 🔧 修复：如果有重写信息，使用重写后的查询
            if rewrite_info and rewrite_info.get('rewritten_query'):
                clean_input = rewrite_info['rewritten_query']
                logger.info(f"使用重写后的查询: {clean_input}")

            # 执行智能体
            result = self.agent.invoke({
                "input": clean_input,
                "user_id": user_id or "default_user"
            })
            
            output = result.get("output", "")
            
            # 如果输出为空或包含错误，提供友好的回复
            if not output or "error" in output.lower():
                output = self._generate_fallback_response(clean_input)
            
            return {
                "success": True,
                "output": output,
                "user_id": user_id,
                "agent": "dingtalk_agent"
            }
            
        except Exception as e:
            logger.error(f"DingTalk agent processing error: {e}")
            return {
                "success": False,
                "output": self._generate_error_response(str(e)),
                "error": str(e),
                "agent": "dingtalk_agent"
            }
    
    def _clean_user_input(self, user_input: str) -> str:
        """清理用户输入，移除对话历史"""
        try:
            # 移除对话历史部分
            if "之前的对话:" in user_input:
                if "当前问题:" in user_input:
                    clean_input = user_input.split("当前问题:")[-1].strip()
                else:
                    clean_input = user_input.split("之前的对话:")[0].strip()
            else:
                clean_input = user_input.strip()
            
            return clean_input
            
        except Exception as e:
            logger.warning(f"Failed to clean user input: {e}")
            return user_input
    
    def _generate_fallback_response(self, user_input: str) -> str:
        """生成备用回复"""
        user_lower = user_input.lower()
        
        if any(keyword in user_lower for keyword in ['待办', '任务', 'todo']):
            return """📋 **钉钉待办功能**

✅ 钉钉API已配置
🔑 App ID: ding2qrtbakupb3st1pb

💡 **可用功能**：
• 创建待办事项
• 查看待办列表
• 完成待办任务

请具体说明您想要创建什么待办事项，我来帮您处理！"""

        elif any(keyword in user_lower for keyword in ['日程', '会议', '安排']):
            return """📅 **钉钉日程功能**

✅ 钉钉API已配置
🔑 App ID: ding2qrtbakupb3st1pb

💡 **可用功能**：
• 查看日程安排
• 创建会议
• 搜索日程
• 修改日程

请告诉我您想要查看什么时间的日程，或者需要创建什么会议！"""

        elif any(keyword in user_lower for keyword in ['联系人', '通讯录', '同事']):
            return """👥 **钉钉联系人功能**

✅ 钉钉API已配置
🔑 App ID: ding2qrtbakupb3st1pb

💡 **可用功能**：
• 搜索联系人
• 查找同事信息
• 获取通讯录

请告诉我您要搜索哪位同事的信息！"""

        else:
            return """🔧 **钉钉办公助手**

✅ 钉钉API已配置
🔑 App ID: ding2qrtbakupb3st1pb

💡 **我可以帮您**：
• 📋 待办事项管理
• 📅 日程安排查询
• 👥 联系人搜索

请具体说明您需要什么帮助！"""
    
    def _generate_error_response(self, error_msg: str) -> str:
        """生成错误回复"""
        return f"""❌ **钉钉功能暂时不可用**

🔑 App ID: ding2qrtbakupb3st1pb
⚠️ 错误信息: {error_msg}

💡 **建议**：
• 请稍后再试
• 检查网络连接
• 联系管理员获取帮助

抱歉给您带来不便！"""

    def get_capabilities(self) -> Dict[str, Any]:
        """获取钉钉智能体的能力信息"""
        return {
            "agent_name": "dingtalk_agent",
            "description": "专业的钉钉办公助手",
            "capabilities": [
                "待办事项管理",
                "日程安排查询",
                "联系人搜索",
                "会议管理"
            ],
            "tools_count": len(self.dingtalk_tools),
            "tools_available": bool(self.dingtalk_tools),
            "agent_ready": bool(self.agent)
        }


def create_dingtalk_agent(dingtalk_tools: List = None) -> DingTalkAgent:
    """
    创建钉钉智能体实例

    Args:
        dingtalk_tools: 钉钉工具列表（可选，如果不提供将自动初始化）

    Returns:
        DingTalkAgent实例
    """
    return DingTalkAgent(dingtalk_tools)


def get_dingtalk_agent(dingtalk_tools: List = None) -> DingTalkAgent:
    """
    获取钉钉智能体（向后兼容）

    Args:
        dingtalk_tools: 钉钉工具列表（可选，如果不提供将自动初始化）

    Returns:
        DingTalkAgent实例
    """
    return create_dingtalk_agent(dingtalk_tools)
